comunidadefandomcom-20200214-history
Módulo:Arguments
Este módulo oferece fácil processamento de argumentos passados para Scribunto a partir do #invoke. -- Ele é destinado para uso por outros módulos Lua, e não deve ser chamado a partir do #invoke diretamente. local libraryUtil = require('libraryUtil') local checkType = libraryUtil.checkType local arguments = {} local nilArg = {} -- Usado para memoizar argumentos nil em metaArgs. -- Gera quatro funções tidyVal diferentes, de modo que não temos que verificar as opções toda vez que nós chamá-las. local function tidyValDefault(key, val) if type(val) 'string' then val = val:match('^%s*(.-)%s*$') if val '' then return nil else return val end else return val end end local function tidyValTrimOnly(key, val) if type(val) 'string' then return val:match('^%s*(.-)%s*$') else return val end end local function tidyValRemoveBlanksOnly(key, val) if type(val) 'string' then if val:find('%S') then return val else return nil end else return val end end local function tidyValNoChange(key, val) return val end function arguments.getArgs(frame, options) checkType('getArgs', 1, frame, 'table', true) checkType('getArgs', 2, options, 'table', true) frame = frame or {} options = options or {} -- Obtém os argumentos do objeto de frame se disponível. Se o objeto de frame não estiver disponível, estamos sendo chamados -- a partir de outro módulo Lua ou do console de depuração, então, atribua os argumentos para uma nova variável para que possamos diferenciá-los. local fargs, pargs, luaArgs if type(frame.args) 'table' and type(frame.getParent) 'function' then if not options.parentOnly then fargs = frame.args end if not options.frameOnly then pargs = frame:getParent().args end if options.parentFirst then fargs, pargs = pargs, fargs end else luaArgs = frame end -- Configura os args e tabelas metaArgs. Os args serão aqueles acessados a partir das funções, e os metaArgs vão segurar os arguments.m atuais. -- A metatable conecta os dois juntos. local args, metaArgs, metatable = {}, {}, {} setmetatable(args, metatable) -- Gera a função tidyVal. Se ela tiver sido especificada pelo usuário, nós usamos isso; se não, nós escolhemos uma das quatro funções -- dependendo das opções escolhidas. Isso é para que nós não tenhamos que chamar a tabela de opções toda vez que a função for chamada. local tidyVal = options.valueFunc if tidyVal then if type(tidyVal) ~= 'function' then error("valor errado atribuído à opção 'valueFunc' (função esperada, obteve " .. type(tidyVal) .. ')', 2) end elseif options.trim ~= false then if options.removeBlanks ~= false then tidyVal = tidyValDefault else tidyVal = tidyValTrimOnly end else if options.removeBlanks ~= false then tidyVal = tidyValRemoveBlanksOnly else tidyVal = tidyValNoChange end end local function mergeArgs(iterator, tables) -- Aceita várias tabelas como entrada e funde suas chaves e valores em uma tabela usando o iterador especificado. -- Se um valor que já está presente não for substituído; as tabelas listadas anteriormente têm precedência. -- Nós também estamos memoizamos valores nil, mas esses valores podem ser substituídos. for _, t in ipairs(tables) do for key, val in iterator(t) do local metaArgsVal = metaArgskey if metaArgsVal nil or metaArgsVal nilArg then local tidiedVal = tidyVal(key, val) if tidiedVal nil then metaArgskey = nilArg else metaArgskey = tidiedVal end end end end end -- Define a ordem de precedência das tabelas de argumento. Se as variáveis forem nil, nada será adicionado à tabela, -- que é como nós evitamos choques entre os args frame/parent e os args Lua. local argTables = {fargs} argTables+ 1 = pargs argTables+ 1 = luaArgs -- -- Define o comportamento da metatable. Os argumentos são memoizados na tabela metaArgs, e só são obtidos a partir das -- tabelas de argumento uma vez. Os argumentos nil também são memoizados usando a variável nilArg, a fim de aumentar a -- performance. Além disso, mantemos um registro na metatable de quando os pairs e ipairs foram chamados, por isso nós -- não executamos pairs e ipairs nos fargs e pargs mais de uma vez. Nós também não executamos ipairs nos fargs e -- args se pairs já foram executados, como todos os argumentos que já terão sido copiados. -- metatable.__index = function (t, key) local val = metaArgskey if val ~= nil then if val nilArg then return nil else return val end end for _, argTable in ipairs(argTables) do local argTableVal = tidyVal(key, argTablekey) if argTableVal nil then metaArgskey = nilArg else metaArgskey = argTableVal return argTableVal end end return nil end metatable.__newindex = function (t, key, val) if options.readOnly then error('não foi possível escrever na chave da tabela do argumento "' .. tostring(key) .. '"; a tabela é somente leitura', 2) elseif options.noOverwrite and argskey ~= nil then error('não foi possível escrever na chave da tabela do argumento "' .. tostring(key) .. '"; substituir argumentos existentes não é permitido', 2) elseif val nil then metaArgskey = nilArg -- Memoiza nils. else metaArgskey = val end end metatable.__pairs = function () if not metatable.donePairs then mergeArgs(pairs, argTables) metatable.donePairs = true metatable.doneIpairs = true end return pairs(metaArgs) end metatable.__ipairs = function () if not metatable.doneIpairs then mergeArgs(ipairs, argTables) metatable.doneIpairs = true end return ipairs(metaArgs) end return args end return arguments